<template>
  <teleport to="body">
    <div
      v-if="show"
      class="z-modal-container outline-none focus:outline-none flex justify-center items-center"
    >
      <z-transition>
        <div ref="el" class="relative w-auto my-6 mx-auto z-20 max-w-4xl">
          <div
            class="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-white outline-none focus:outline-none"
          >
            <div
              class="flex items-center justify-between p-6 border-b border-solid border-blueGray-200 rounded-t"
            >
              <slot name="header">
                <h3 class="text-xl font-semibold">
                  {{ title }}
                </h3>
              </slot>
              <svg
                class="w-6 h-6 text-gray-500 stroke-cap-round stroke-join-round stroke-3 cursor-pointer"
                stroke="currentColor"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
                @click="cancel"
              >
                <path d="M6 18L18 6M6 6l12 12" />
              </svg>
            </div>
            <div class="relative p-6 flex-auto">
              <slot></slot>
            </div>
            <div
              class="flex items-center justify-end space-x-2 p-6 border-t border-solid border-blueGray-200 rounded-b"
            >
              <slot name="footer">
                <z-button v-if="cancelButton" outline @click="cancel">
                  {{ cancelText }}
                </z-button>
                <z-button @click="ok">
                  {{ okText }}
                </z-button>
              </slot>
            </div>
          </div>
        </div>
      </z-transition>
      <div class="opacity-25 absolute inset-0 z-10 bg-black"></div>
    </div>
  </teleport>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from "vue";
import { onClickOutside } from "@vueuse/core";
import ZButton from "./ZButton.vue";
import ZTransition from "./ZTransition.vue";

export default defineComponent({
  name: "ZModal",
  components: {
    ZButton,
    ZTransition,
  },
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    title: String,
    cancelButton: Boolean,
    cancelText: {
      default: "取消",
    },
    okText: {
      default: "确定",
    },
  },
  emits: ["update:show", "ok", "cancel", "open", "close"],
  setup(props, { emit }) {
    const el = ref(),
      cancel = () => {
        emit("update:show", false);
        emit("cancel");
      },
      ok = () => {
        emit("ok");
      };
    // 当点击模态框外部时，关闭模态框。
    onClickOutside(el, cancel);
    // 添加 model 显示和关闭事件
    watch(
      () => props.show,
      (val) => {
        if (val) emit("open");
        else emit("close");
      }
    );
    return {
      el,
      cancel,
      ok,
    };
  },
});
</script>
<style>
.z-modal-container {
  @apply overflow-x-hidden overflow-y-auto fixed inset-0 z-30;
}
</style>
